package java.util.stream.reentrant_lock;


public final class FairSync extends Sync {
    private static final long serialVersionUID = -3000897897090466540L;

    final void lock() {
        // 尝试获取锁
        acquire(1);
    }

    /**
     * 公平的tryAcquire版本
     * 除非递归调用或没有服务员，否则不要授予访问权限。
     * 如果不是下面三种情况的时候，不会授予访问权限，递归调用,没有等待者或者第一个
     * Don't grant access unless recursive call or no waiters or is first.
     */
    protected final boolean tryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        if (c == 0) {
            // 和非公平版本相比，只是多加了 hasQueuedPredecessors() 这个判断
            // 对比所有线程的等待时间，如果不存在比当前线程等待时间更长的线程。
            // 只需要判断当前线程是否和队列中的第一个线程是否为同一条线程即可。
            if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                // 设置当前拥有独占访问权的线程
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        else if (current == getExclusiveOwnerThread()) {
            // 可重入的实现
            int nextc = c + acquires;
            if (nextc < 0)
                throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        return false;
    }
}